/*
 * Control.java
 * Team qq 2011
 */
package com.google.code.timetrail.backend;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Acts as the controller for the game as it contains all the objects that make
 * up the game (will be a singleton in the future)
 * 
 * @author Anuraag
 * @version 1.1
 * 
 */

public class Control implements Serializable {

	/**
	 * the version ID of Control, CHANGE IT if control gets incompatibly changed
	 **/
	private static final long serialVersionUID = 10L;

	/** The "main character" of the game */
	private Person player;

	/** The party of people in your ship */
	private List<Person> members;

	/** The player's Inventory */
	private Inventory inv;

	/** The pace at which the ship is currently moving */
	private TravelSpeed pace;

	/** The rate at which the party is consuming food */
	private ConsumptionRate rations;

	/** The ship the party is currently in */
	private Spaceship ship;

	/** The time stream the party travels through */
	private Time time;

	/** The last place visited by the ship */
	private Place lastPlace;

	/** The current place the ship is at */
	private Place currentPlace;

	/** The next event to occur. Is null if there is no event (unsafe) **/
	private Event nextEvent;

	/**Divides certain operations with this number*/
	private static final int DIVIDENUMBERBY = 20;
	
	/**
	 * Instantiates all the starting objects to their default state
	 */
	public Control() {
		player = new Person();
		members = new ArrayList<Person>();
		members.add(player);
		inv = new Inventory();
		pace = TravelSpeed.STOPPED;
		rations = ConsumptionRate.NONE;
		ship = new Spaceship();
		time = new Time();
		lastPlace = Place.INDEPENDENCE;
		currentPlace = Place.INDEPENDENCE;
		nextEvent = new Event();

	}

	/**
	 * The method that uses the objects controller has to "take a turn"
	 * PRECONDITION: the option to change pace/rations has already been given
	 * POSTCONDITIONS: distance traveled gets incremented based on pace food
	 * gets reduced based on rations
	 */
	public void takeATurn() {
		final int perPersonRations = getRations().getPerPersonCon();
		final Place nextPlace = lastPlace.findNextPlace();
		time.incrementTurn();
		time.incrementTimeTraveled(getPace().getPerTurnDistance()
				+ player.getSkills()[1] / DIVIDENUMBERBY);

		if (nextPlace.getLocation() <= time.getTimeTraveled()) {
			// A Place has been reached
			time.setTimeTraveled(nextPlace.getLocation());
			this.setLastPlace(nextPlace);
			this.setCurrentPlace(nextPlace);
			// put store/river handing here I guess
		} else {
			this.setCurrentPlace(Place.TRANSIT);
		}
		for (Person person : getMembers()) {
			if (!person.getStatus().equals("Dead")
					&& inv.canRemoveItem(perPersonRations, inv.getFood())) {
				inv.removeItem(perPersonRations, inv.getFood());
			} else if (!person.getStatus().equals("Dead")) {
				inv.getFood().setCurrentAmount(0);
			}
		}
		// if(inv.canRemoveItem(perPersonRations
		// + (perPersonRations) * getMembers().size(), inv.getFood())){
		// inv.removeItem(perPersonRations
		// + (perPersonRations) * getMembers().size(), inv.getFood());
		// }

	}

	/**
	 * Gets the player object from Control
	 * 
	 * @return the player
	 */
	public Person getPlayer() {
		return player;
	}

	/**
	 * returns the list of members in the space ship's party
	 * 
	 * @return members
	 */
	public final List<Person> getMembers() {

		return members;
	}

	/**
	 * returns the party's current Inventory
	 * 
	 * @return inv
	 */
	public Inventory getInv() {
		return inv;
	}

	/**
	 * Returns the pace at which the ship is currently traveling
	 * 
	 * @return pace
	 */
	public TravelSpeed getPace() {
		return pace;
	}

	/**
	 * Returns the rate at which the party is consuming food
	 * 
	 * @return rations
	 */
	public ConsumptionRate getRations() {
		return rations;
	}

	/**
	 * Returns the spaceship that the party is currently in
	 * 
	 * @return ship
	 */
	public Spaceship getShip() {
		return ship;
	}

	/**
	 * Gets the timestream the party is traveling on
	 * 
	 * @return the timestream
	 */
	public Time getTime() {
		return time;
	}

	/**
	 * Gets the last place the party visited
	 * 
	 * @return the last place
	 */
	public Place getLastPlace() {
		return lastPlace;
	}

	/**
	 * The current place the wagon is at
	 * 
	 * @return null if on the road and the place name otherwise
	 */
	public Place getCurrentPlace() {
		return currentPlace;
	}

	/**
	 * the next event in the event queue to happen
	 * 
	 * @return the next event
	 */
	public Event getNextEvent() {
		return nextEvent;
	}

	/**
	 * Gives a randomly selected Event. These all occur with an equal
	 * opportunity.
	 * 
	 * @return a randomly selected Event
	 */
	public Event getRandomEvent() {
		final Random rand = new Random();
		final Event damagedShipEvent = new DamagedShipEvent(this);
		final Event noEvent = new Event();
		final Event playerDeathEvent = new PlayerDeathEvent(this);
		final Event playerSickEvent = new PlayerIllnessEvent(this);
		final Event playerRecoveredEvent = new PlayerRecoveredEvent(this);
		final Event[] eventArray = { damagedShipEvent, noEvent, playerDeathEvent,
				playerSickEvent, playerRecoveredEvent };
		return eventArray[rand.nextInt(eventArray.length)];
	}

	/**
	 * Sets the main character of the game
	 * 
	 * @param player
	 *            the player to become the main character
	 */
	public void setPlayer(Person player) {
		this.player = player;
	}

	/**
	 * Set the group of people (besides the main character) who are in the party
	 * 
	 * @param members
	 *            People to become the party
	 */
	public void setMembers(List<Person> members) {
		this.members = members;

	}

	/**
	 * Set the inventory the party is using to store their items
	 * 
	 * @param inv
	 *            the inventory to be used
	 */
	public void setInv(Inventory inv) {
		this.inv = inv;
	}

	/**
	 * Set the pace at which the ship moves through time
	 * 
	 * @param pace
	 *            the speed of the space ship
	 */
	public void setPace(TravelSpeed pace) {
		this.pace = pace;
	}

	/**
	 * Set the rate at which the party consumes food
	 * 
	 * @param rations
	 *            the rate for them to consume at
	 */
	public void setRations(ConsumptionRate rations) {
		this.rations = rations;
	}

	/**
	 * Set the space ship that the party is using to travel
	 * 
	 * @param ship
	 *            the ship to become the party's ship
	 */
	public void setShip(Spaceship ship) {
		this.ship = ship;
	}

	/**
	 * Set the timestream the party is traveling through
	 * 
	 * @param time
	 *            the timestream being used to travel
	 */
	public void setTime(Time time) {
		this.time = time;
	}

	/**
	 * Set the last place the party visited
	 * 
	 * @param lastPlace
	 *            the intended last place the party visited
	 */
	public void setLastPlace(Place lastPlace) {
		this.lastPlace = lastPlace;
	}

	/**
	 * Sets the current place parameter to what you need it to be
	 * 
	 * @param currentPlace
	 *            the current place you're at
	 */
	public void setCurrentPlace(Place currentPlace) {
		this.currentPlace = currentPlace;
	}

	/**
	 * Sets the event for the next event
	 * 
	 * @param nextEvent The nextEvent
	 */
	public void setNextEvent(Event nextEvent) {
		this.nextEvent = nextEvent;
	}

	/**
	 * Returns a string representation for Controller
	 * 
	 * @return player, inv, pace, rations, and ship's toString
	 */
	@Override
	public String toString() {
		return "Controller: " + player + " " + inv + " " + pace + " " + rations
				+ " " + ship + " " + time;
	}
}
